import { InjectRedis } from "@nestjs-modules/ioredis";
import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import Redis from 'ioredis';
import { RepeatSubmitOption } from "../decorators/repeat-submit.decorator";
import { REOEATSUBMIT_METADATA } from "../contants/decorator.contants";
import { ApiException } from "../exceptions/api.exceptions";

@Injectable()
export class RepeatSubmitGuard implements CanActivate {
    constructor(private readonly reflector: Reflector, @InjectRedis() private readonly redis: Redis) { }
    
    async canActivate(context: ExecutionContext): Promise<boolean> {
        const repeatSubmitOption: RepeatSubmitOption = this.reflector.get(REOEATSUBMIT_METADATA, context.getHandler())
        if (!repeatSubmitOption) return true;
        const request = context.switchToHttp().getRequest();
        const cache = await this.redis.get(request.url);
        const data = {
            body: request.body,
            prams: request.params,
            query: request.query
        }
        const dataString = JSON.stringify(data);
        if (!cache) {
            if (dataString) {
                await this.redis.set(
                    request.url,
                    dataString,
                    "EX",
                    repeatSubmitOption.interval
                );
            }
        } else {
            if (dataString && cache === dataString) {
                throw new ApiException(repeatSubmitOption.message, 400);
            }
        }
        return true;
    }
}